package com.xzx.framework.util.http;


import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;

import javax.net.ssl.SSLException;

import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.protocol.HttpContext;


/**
 * 异常恢复机制 连接失败后，可以针对相应的异常进行相应的处理措施；
 * 
 * @author wei
 * @time 2015年11月1日 下午9:37:35
 */
public class HttpRequestRetryHandler implements org.apache.http.client.HttpRequestRetryHandler {
	private static HttpRequestRetryHandler instance = null;
	
	private HttpRequestRetryHandler(){}
	
	public static HttpRequestRetryHandler getInstance(){
		if(instance == null) {
			synchronized (HttpRequestRetryHandler.class) {
				if(instance == null) {
					instance = new HttpRequestRetryHandler();
				}
			}
		}
		
		return instance;
	}
	
	public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
		if (executionCount >= 5) {// 如果连接次数超过5次，就不进行重复连接
			return false;
		}
		if (exception instanceof InterruptedIOException) {// io操作中断
			return false;
		}
		if (exception instanceof UnknownHostException) {// 未找到主机
			// Unknown host
			return false;
		}
		if (exception instanceof ConnectTimeoutException) {// 连接超时
			return true;
		}
		if (exception instanceof SSLException) {
			// SSL handshake exception
			return false;
		}
		HttpClientContext clientContext = HttpClientContext.adapt(context);
		HttpRequest request = clientContext.getRequest();
		boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);

		if (idempotent) {
			// Retry if the request is considered idempotent
			return true;
		}
		return false;
	}
}
